#include "sys.h"
#include "bsp.h"
#include "iap.h"
#include "fatfs.h"
#include "log.h"
#include "string.h"
#include "systick.h"
iapfun jump2app; 

#define BUF_SIZE   20*1024
uint8_t data_buf[BUF_SIZE];
static uint8_t SD_drivers = 0;
uint32_t firmware_size = 0;
uint32_t crc_read = 0;
static	uint32_t crc_write = 0;
uint8_t readfileerror = 1;
//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(uint32_t appxaddr)
{
	if(((*(__IO uint32_t*)appxaddr)&0x2FFE0000)==0x20000000)	//检查栈顶地址是否合法.
	{ 
		jump2app=(iapfun)*(__IO uint32_t*)(appxaddr+4);		//用户代码区第二个字为程序开始地址(复位地址)		
		MSR_MSP(*(__IO uint32_t*)appxaddr);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
		jump2app();									//跳转到APP.
	}
}		 

void iap_init(void)
{
	if(Fatfs_init(SDCard))
	{
		log_info("find sd card!");
		SD_drivers = 1; 
	}
}


uint8_t iap_check_file(void)
{
	uint8_t res = 0;
	uint32_t index = 0;
	if(SD_drivers)
	{
		if(Fatfs_open(SDCard,"firmware.bin",FA_OPEN_EXISTING|FA_READ))
		{
			log_info("SD not found firmware!");
			res = 0;
		}else{
			log_info("SD  find firmware!");
			firmware_size = openfile.fsize;
			crc_data_register_reset();
			crc_read = 0;
			for(index = 0;index <= firmware_size;index += BUF_SIZE)
			{
				if(!Fatfs_read(data_buf,BUF_SIZE))
				{
					readfileerror = 0;
			     	crc_read = crc_block_data_calculate((uint32_t *)data_buf,BUF_SIZE/4);
				}
			}
			Fatfs_close();
			log_info("read file CRC is %x",crc_read);
			res = 1;
		}
	}
	else{
		log_info("Not found SD Card!");
	}
	return res;
}

uint8_t iap_check_update(void)
{
	uint8_t res;
	uint8_t retry = 0;
	uint32_t *crc_inflash = (uint32_t*)CRC_FLASH_ADDR;
//	log_info("Wait for USB Host!");
//	delay_1ms(200);   //delay for usb host proecss
	// if(Udisk_drivers)
	// {
	// 	log_info("Found USB Disk!");
	// 		while(readfileerror  && retry < 5)
	// 		{
	// 				delay_1ms(200);   //delay for usb host proecss
	// 		  	retry++;
	// 		}
	// 		if(retry > 5)
	// 		{
	// 			log_info("Not file or read file error!!");
	// 		}
	// }
	if(SD_drivers && readfileerror ==0)
	{
		if((crc_read ==0) || crc_read == *crc_inflash)
		{
			res =  1;
			log_info("CRC check equal, not need to update firmware");
		}
		else res = 0;
	}
	else res = 1;
	return res;
}

void iap_update_fimware(void)
{
	uint8_t *uid = (uint8_t*)UID_ADDR;
	uint32_t index;
	if(SD_drivers){
		if(readfileerror == 0)
		{
			log_info("Firmware erasing");
			erase_flash(FLASH_APP1_END_ADDR - CRC_FLASH_ADDR,CRC_FLASH_ADDR);;
			log_info("Firmware erase done!");

			log_info("Firmware updating");
			if(Fatfs_open(SDCard,"firmware.bin",FA_OPEN_EXISTING|FA_READ))
			{
				log_info("firmware open error!");
			}
			for(index = 0;index <= firmware_size;index += BUF_SIZE)
			{
				if(!Fatfs_read(data_buf,BUF_SIZE))
				{
					writeToFlash((char *)data_buf,BUF_SIZE,FLASH_APP1_ADDR+index);
				}
			}
			Fatfs_close();
			log_info("Firmware update done!");
			crc_data_register_reset();
			crc_write = crc_block_data_calculate((uint32_t *)FLASH_APP1_ADDR,index/4);
			log_info("check wirte CRC:%x",crc_write);
			if(crc_write == crc_read)
			{
				log_info("Firmware update success!");
				writeToFlash((char *)&crc_write,sizeof(crc_write),CRC_FLASH_ADDR);
				NVIC_SystemReset();
			}
			else{
				log_info("CRC not equal, Firmware update error!");
			}
		}else{
				log_info("read file error!!!");			
		}
	}
	else{
		log_info("Not find SD Card !");
	}
}











